/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Negocio;

import Dominio.Estado;
import Dominio.Nodo;
import java.util.LinkedList;

/**
 *
 * @author beatriz
 */
public class TempleSimulado {

    private int origen;
    private int destino;
    private int maxDistancia;
    private int maxBares;
    private int maxOcio;
    private int cota;

    public TempleSimulado(int origen, int destino, int maxDistancia, int maxBares, int maxOcio, int cota) {
        this.origen = origen;
        this.destino = destino;
        this.maxDistancia = maxDistancia;
        this.maxBares = maxBares;
        this.maxOcio = maxOcio;
        this.cota = cota;
    }

    public Nodo lanzarTempleSimulado(Nodo solucion) {
        Nodo solActual = (Nodo) solucion.clone();
        Nodo solFinal = (Nodo) solucion.clone();
        Nodo solCandidata = null;
        int temperatura = 999;//MIRAR QUE TEMPERATURA INCIAL PONGO
        float dE = (float) 0.0; //Incemento de energía
        double aleatorio;

        while (temperatura > 0) {
            for (int i = 0; i < 1000 - temperatura; i++) {
                solCandidata = caminoVecino((Nodo) solActual.clone());
//                System.out.println("----------------------------");
//                System.out.println("Actual : " + solActual.toString());
//                System.out.println("Vecina : " + solCandidata.toString());
//                System.out.println("----------------------------");


                dE = (float) (solCandidata.getCoste() - solActual.getCoste());
//                System.out.println("coste candidata :" + solCandidata.getCoste());
//                System.out.println("Coste actual :" + solActual.getCoste());

                if (dE > 0.0) {
                    solActual = (Nodo) solCandidata.clone();
                } else {
                    aleatorio = Math.random();
                    if (aleatorio <= Math.exp(dE / temperatura)) {
                        solActual = (Nodo) solCandidata.clone();
                    }
                }

            }
            if (solActual.getCoste() < solFinal.getCoste()) {
                solFinal = (Nodo) solActual.clone();
            }
            temperatura -= 66;

        }
        return solFinal;

    }

    private Nodo caminoVecino(Nodo s) {
//        Nodo caminoVecino = null;
//        Nodo subSolucion = null;
//        Busqueda buscador;
//
//        LinkedList<Integer> caminoTotal = new LinkedList<Integer>();
//
//        LinkedList<Integer> camino = convertirLista(solucion);
//        int puntoIntermedioA = (int) (Math.random() * (camino.size() - 1)) + 1;
//        int puntoIntermedioB = (int) (Math.random() * (camino.size() - 1)) + 1;
//
//        while (puntoIntermedioA >= puntoIntermedioB || Math.abs(puntoIntermedioA - puntoIntermedioB) < 1) {
//            puntoIntermedioB = (int) (Math.random() * (camino.size() - 1)) + 1;
//        }
//
//        origen = camino.get(puntoIntermedioA);
//        destino = camino.get(puntoIntermedioB);
//
//        buscador = new Busqueda(origen, destino, tipoBusqueda, maxDistancia, maxBares, maxOcio);
//        subSolucion = buscador.lanzarBusqueda(cota);
//
//        /////////////////
//        LinkedList<Integer> subcamino = convertirLista(subSolucion);
//
//        for (int i = 0; i< puntoIntermedioA;i++){
//            caminoTotal.addLast(camino.get(i));
//        }
//
//        caminoTotal.addAll(subcamino);
//        for(int i = puntoIntermedioB; i<camino.size();i++){
//            caminoTotal.add(subcamino.get(i));
//        }
//
//        return caminoVecino;


        Nodo solucionInicial = (Nodo) s.clone();

        Nodo nodoFinal, subSolucion;
//        System.out.println("Longitud solucion: " + longitudSolucion(solucionInicial));
        int a = (int) (Math.random() * (longitudSolucion(solucionInicial) - 1)) + 1;
//        int a = (int) (Math.random() * (longitudSolucion(solucionInicial)-1))+1;
        int b = (int) (Math.random() * (longitudSolucion(solucionInicial) - 1)) + 1;
        int aux;

//        if(a < b){
//           aux = b;
//           b = a;
//           a = aux;
//         }
        while (a <= b) {
            a = (int) (Math.random() * (longitudSolucion(solucionInicial) - 1)) + 1;
            b = (int) (Math.random() * (longitudSolucion(solucionInicial) - 1)) + 1;
        }


        // nodoInicial = Funciones.getNodoIntermedio(a, solucionInicial);
        nodoFinal = getNodoIntermedio(b, solucionInicial);
        // nodoEnlace = Funciones.getNodoIntermedio(b-1, solucionInicial);
        Busqueda buscador = new Busqueda(getNodoIntermedio(a, solucionInicial).getEstado().getIdNodo(), nodoFinal.getEstado().getIdNodo(), 4, maxDistancia, maxBares, maxOcio);
        buscador.setNodoInicial(getNodoIntermedio(a, solucionInicial));
        subSolucion = buscador.lanzarBusqueda(1);

        getNodoIntermedio(b - 1, solucionInicial).setNodoPadre(subSolucion);
        return solucionInicial;
    }

    private int longitudSolucion(Nodo sol) {
        int longitud = 1;
        Nodo nodoAux = sol;
        while (nodoAux.getNodoPadre() != null) {
            nodoAux = nodoAux.getNodoPadre();
            longitud = longitud + 1;
        }
        return longitud;
    }

    private Nodo getNodoIntermedio(int k, Nodo n) {
        if (k == 0) {
            return n;
        } else {
            return getNodoIntermedio(k - 1, n.getNodoPadre());
        }
    }

    private LinkedList<Integer> convertirLista(Nodo n) {
        Nodo aux = n;
        LinkedList<Integer> lista = new LinkedList<Integer>();
        while (aux.getNodoPadre() != null) {
            lista.addFirst(aux.getEstado().getIdNodo());
            aux = aux.getNodoPadre();
        }
        return lista;
    }
}
